package com.tyut.musicdreamer.service.music.task;

import com.tyut.musicdreamer.service.music.model.entity.Music;
import com.tyut.musicdreamer.service.music.service.MusicService;
import com.tyut.musicdreamer.service.music.service.impl.StorageServiceAdapter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 音乐存储类别更新定时任务
 * 基于播放次数智能调整音乐文件存储类别
 */
@Component("musicStorageClassUpdateTask")
@Slf4j
public class MusicStorageClassUpdateTask {

    private final MusicService musicService;
    private final StorageServiceAdapter storageServiceAdapter;
    
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String PLAY_COUNT_CACHE_KEY = "music:play_count:";
    
    /**
     * 构造方法
     * @param storageServiceAdapter 存储服务适配器
     * @param musicService 音乐服务
     */
    public MusicStorageClassUpdateTask(StorageServiceAdapter storageServiceAdapter, MusicService musicService) {
        this.storageServiceAdapter = storageServiceAdapter;
        this.musicService = musicService;
    }
    
    /**
     * 每天凌晨3点执行音乐存储类别更新
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void updateStorageClass() {
        log.info("开始执行音乐存储类别更新任务");
        
        // 1. 获取所有音乐
        List<Music> allMusic = musicService.list();
        
        // 2. 遍历音乐检查播放次数并更新存储类别
        int updatedCount = 0;
        for (Music music : allMusic) {
            try {
                String id = music.getId();
                String fileUrl = music.getFileUrl();
                
                if (fileUrl == null || fileUrl.isEmpty()) {
                    continue;
                }
                
                // 获取播放次数
                long playCount = getPlayCount(id, music.getPlayCount());
                
                // 确定合适的存储类别
                String targetStorageClass = determineStorageClassByPlayCount(playCount);
                
                // 检查是否需要更新
                if (needUpdate(music.getStorageClass(), targetStorageClass)) {
                    log.info("更新音乐 {} 的存储类别为 {}, 播放次数: {}", id, targetStorageClass, playCount);
                    
                    // 更新存储类别
                    boolean success = storageServiceAdapter.updateStorageClass(fileUrl, targetStorageClass);
                    
                    if (success) {
                        // 更新数据库中的存储类别和播放次数
                        music.setStorageClass(targetStorageClass);
                        music.setPlayCount(playCount);
                        musicService.updateById(music);
                        
                        // 清除播放次数缓存
                        redisTemplate.delete(PLAY_COUNT_CACHE_KEY + id);
                        
                        updatedCount++;
                    }
                }
            } catch (Exception e) {
                log.error("处理音乐 {} 的存储类别时出错", music.getId(), e);
            }
        }
        
        log.info("音乐存储类别更新任务完成，共更新 {} 个音乐的存储类别", updatedCount);
    }
    
    /**
     * 获取播放次数（从Redis和数据库）
     */
    private long getPlayCount(String musicId, Long dbPlayCount) {
        // 从Redis获取播放次数
        Object countObj = redisTemplate.opsForValue().get(PLAY_COUNT_CACHE_KEY + musicId);
        long redisPlayCount = 0;
        
        if (countObj instanceof Long) {
            redisPlayCount = (Long) countObj;
        } else if (countObj instanceof Integer) {
            redisPlayCount = ((Integer) countObj).longValue();
        } else if (countObj instanceof String) {
            redisPlayCount = Long.parseLong((String) countObj);
        } else if (countObj != null) {
            redisPlayCount = Long.parseLong(countObj.toString());
        }
        
        // 添加数据库中已记录的播放次数
        long totalPlayCount = redisPlayCount;
        if (dbPlayCount != null) {
            totalPlayCount += dbPlayCount;
        }
        
        return totalPlayCount;
    }
    
    /**
     * 根据播放次数确定存储类别
     */
    private String determineStorageClassByPlayCount(long playCount) {
        if (playCount > 10000) {
            return "Standard";
        } else if (playCount > 1000) {
            return "IA";
        } else {
            return "Archive";
        }
    }
    
    /**
     * 检查是否需要更新存储类别
     */
    private boolean needUpdate(String currentStorageClass, String targetStorageClass) {
        if (currentStorageClass == null) {
            return true;
        }
        
        return !currentStorageClass.equalsIgnoreCase(targetStorageClass);
    }
} 